#include <graphics/mesh.h>
#include <assert.h>
#include <graphics/vertexbuffer.h>
#include <graphics/indexbuffer.h>
#include <graphics/camera.h>
#include <QGLShaderProgram>
#include <graphics/utils.h>

namespace yam3d
{
namespace graphics
{

Mesh::Mesh(VertexBuffer* vb, IndexBuffer* ib)
    : Node()
    , m_vb(vb)
    , m_ib(ib)
{
    assert(vb != 0);
    assert(ib != 0);
}

Mesh::~Mesh()
{
    SAFE_DELETE(m_vb);
    SAFE_DELETE(m_ib);
}

VertexBuffer* Mesh::getVertexBuffer() const
{
    assert(m_vb != 0);
    return m_vb;
}

IndexBuffer* Mesh::getIndexBuffer() const
{
    assert(m_ib != 0);
    return m_ib;
}

void Mesh::renderGeometryWithShader(QGLShaderProgram* program, Camera* camera )
{
    // Set uniform values for matrices
    math::mat4 matModel = getTransform();
    math::mat4 matView = camera->getView();
    math::mat4 matProj = camera->getProjection();
    math::mat4 matWorldView = matView.inverted();
    math::mat4 matModelView = matWorldView * matModel;
    math::mat4 matModelViewInverseTranspose = matModelView.inverted().transposed();
    math::mat4 matModelViewProj = matProj * matModelView;

    program->setUniformValue("vecEyePositionWorld", camera->getTranslation() );

    program->setUniformValue("matModel", matModel );
    program->setUniformValue("matView", matView );
    program->setUniformValue("matProj", matProj );
    program->setUniformValue("matWorldView", matWorldView );
    program->setUniformValue("matModelView", matModelView );
    program->setUniformValue("matModelViewInverseTranspose", matModelViewInverseTranspose );
    program->setUniformValue("matModelViewProj", matModelViewProj );

    getVertexBuffer()->setVertexArrays(program);
    getIndexBuffer()->draw();
}


}
}

